home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 338_01 / analyze.c < prev    next >
Text File  |  1989-11-28  |  17KB  |  483 lines

  1. #include        <stdio.h>
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or questions
  18.  *    to:
  19.  *
  20.  *        Matthew Brandt
  21.  *        Box 920337
  22.  *        Norcross, Ga 30092
  23.  */
  24.  
  25. extern struct amode     push[], pop[];
  26.  
  27. /*
  28.  *      this module will step through the parse tree and find all
  29.  *      optimizable expressions. at present these expressions are
  30.  *      limited to expressions that are valid throughout the scope
  31.  *      of the function. the list of optimizable expressions is:
  32.  *
  33.  *              constants
  34.  *              global and static addresses
  35.  *              auto addresses
  36.  *              contents of auto addresses.
  37.  *
  38.  *      contents of auto addresses are valid only if the address is
  39.  *      never referred to without dereferencing.
  40.  *
  41.  *      scan will build a list of optimizable expressions which
  42.  *      opt1 will replace during the second optimization pass.
  43.  */
  44.  
  45. static struct cse       *olist;         /* list of optimizable expressions */
  46.  
  47. equalnode(node1, node2)
  48. /*
  49.  *      equalnode will return 1 if the expressions pointed to by
  50.  *      node1 and node2 are equivalent.
  51.  */
  52. struct enode    *node1, *node2;
  53. {       if( node1 == 0 || node2 == 0 )
  54.                 return 0;
  55.         if( node1->nodetype != node2->nodetype )
  56.                 return 0;
  57.         if( (node1->nodetype == en_icon || node1->nodetype == en_labcon ||
  58.             node1->nodetype == en_nacon || node1->nodetype == en_autocon) &&
  59.             node1->v.i == node2->v.i )
  60.                 return 1;
  61.         if( lvalue(node1) && equalnode(node1->v.p[0], node2->v.p[0]) )
  62.                 return 1;
  63.         return 0;
  64. }
  65.  
  66. struct cse      *searchnode(node)
  67. /*
  68.  *      searchnode will search the common expression table for an entry
  69.  *      that matches the node passed and return a pointer to it.
  70.  */
  71. struct enode    *node;
  72. {       struct cse      *csp;
  73.         csp = olist;
  74.         while( csp != 0 ) {
  75.                 if( equalnode(node,csp->exp) )
  76.                         return csp;
  77.                 csp = csp->next;
  78.                 }
  79.         return 0;
  80. }
  81.  
  82. struct enode    *copynode(node)
  83. /*
  84.  *      copy the node passed into a new enode so it wont get
  85.  *      corrupted during substitution.
  86.  */
  87. struct enode    *node;
  88. {       struct enode    *temp;
  89.         if( node == 0 )
  90.                 return 0;
  91.         temp = (struct enode *) xalloc(sizeof(struct enode));
  92.         temp->nodetype = node->nodetype;
  93.         temp->v.p[0] = node->v.p[0];
  94.         temp->v.p[1] = node->v.p[1];
  95.         return temp;
  96. }
  97.  
  98. enternode(node,duse)
  99. /*
  100.  *      enternode will enter a reference to an expression node into the
  101.  *      common expression table. duse is a flag indicating whether or not
  102.  *      this reference will be dereferenced.
  103.  */
  104. struct enode    *node;
  105. int             duse;
  106. {       struct cse      *csp;
  107.         if( (csp = searchnode(node)) == 0 ) {   /* add to tree */
  108.                 csp = (struct cse *)xalloc(sizeof(struct cse));
  109.                 csp->next = olist;
  110.                 csp->uses = 1;
  111.                 csp->duses = (duse != 0);
  112.                 csp->exp = copynode(node);
  113.                 csp->voidf = 0;
  114.                 olist = csp;
  115.                 return csp;
  116.                 }
  117.         ++(csp->uses);
  118.         if( duse )
  119.                 ++(csp->duses);
  120.         return csp;
  121. }
  122.  
  123. struct cse      *voidauto(node)
  124. /*
  125.  *      voidauto will void an auto dereference node which points to
  126.  *      the same auto constant as node.
  127.  */
  128. struct enode    *node;
  129. {       struct cse      *csp;
  130.         csp = olist;
  131.         while( csp != 0 ) {
  132.                 if( lvalue(csp->exp) && equalnode(node,csp->exp->v.p[0]) ) {
  133.                         if( csp->voidf )
  134.                                 return 0;
  135.                         csp->voidf = 1;
  136.                         return csp;
  137.                         }
  138.                 csp = csp->next;
  139.                 }
  140.         return 0;
  141. }
  142.  
  143. scanexpr(node,duse)
  144. /*
  145.  *      scanexpr will scan the expression pointed to by node for optimizable
  146.  *      subexpressions. when an optimizable expression is found it is entered
  147.  *      into the tree. if a reference to an autocon node is scanned the
  148.  *      corresponding auto dereferenced node will be voided. duse should be
  149.  *      set if the expression will be dereferenced.
  150.  */
  151. struct enode    *node;
  152. {       struct cse      *csp, *csp1;
  153.         int             n;
  154.         if( node == 0 )
  155.                 return;
  156.         switch( node->nodetype ) {
  157.                 case en_icon:
  158.                 case en_labcon:
  159.                 case en_nacon:
  160.                         enternode(node,duse);
  161.                         break;
  162.                 case en_autocon:
  163.                         if( (csp = voidauto(node)) != 0 ) {
  164.                                 csp1 = (struct cse *)enternode(node,duse);
  165.                                 csp1->uses = (csp1->duses += csp->uses);
  166.                                 }
  167.                         else
  168.                                 enternode(node,duse);
  169.                         break;
  170.                 case en_b_ref:
  171.                 case en_w_ref:
  172.                 case en_l_ref:
  173.                         if( node->v.p[0]->nodetype == en_autocon ) {
  174.                                 csp = (struct cse *) enternode(node,duse);
  175.                                 if( csp->voidf )
  176.                                         scanexpr(node->v.p[0],1);
  177.                                 }
  178.                         else
  179.                                 scanexpr(node->v.p[0],1);
  180.                         break;
  181.                 case en_cbl:    case en_cwl:
  182.                 case en_cbw:    case en_uminus:
  183.                 case en_compl:  case en_ainc:
  184.                 case en_adec:   case en_not:
  185.                         scanexpr(node->v.p[0],duse);
  186.                         break;
  187.                 case en_asadd:  case en_assub:
  188.                 case en_add:    case en_sub:
  189.                         scanexpr(node->v.p[0],duse);
  190.                         scanexpr(node->v.p[1],duse);
  191.                         break;
  192.                 case en_mul:    case en_div:
  193.                 case en_lsh:    case en_rsh:
  194.                 case en_mod:    case en_and:
  195.                 case en_or:     case en_xor:
  196.                 case en_lor:    case en_land:
  197.                 case en_eq:     case en_ne:
  198.                 case en_gt:     case en_ge:
  199.                 case en_lt:     case en_le:
  200.                 case en_asmul:  case en_asdiv:
  201.                 case en_asmod:  case en_aslsh:
  202.                 case en_asrsh:  case en_asand:
  203.                 case en_asor:   case en_cond:
  204.                 case en_void:   case en_assign:
  205.                         scanexpr(node->v.p[0],0);
  206.                         scanexpr(node->v.p[1],0);
  207.                         break;
  208.                 case en_fcall:
  209.                         scanexpr(node->v.p[0],1);
  210.                         scanexpr(node->v.p[1],0);
  211.                         break;
  212.                 }
  213. }
  214.  
  215. scan(block)
  216. /*
  217.  *      scan will gather all optimizable expressions into the expression
  218.  *      list for a block of statements.
  219.  */
  220. struct snode    *block;
  221. {       while( block != 0 ) {
  222.                 switch( block->stype ) {
  223.                         case st_return:
  224.                         case st_expr:
  225.                                 opt4(&block->exp);
  226.                                 scanexpr(block->exp,0);
  227.                                 break;
  228.                         case st_while:
  229.                         case st_do:
  230.                                 opt4(&block->exp);
  231.                                 scanexpr(block->exp,0);
  232.                                 scan(block->s1);
  233.                                 break;
  234.